import pyautogui
import cv2
import numpy as np
import time
import pytesseract
import win32gui
import win32con
import dxcam
import sys
from PIL import Image

# ===== 配置区域 =====
# 播放器窗口标题（完整或部分标题）
PLAYER_WINDOW_TITLE = "EVPlayer2"

# 结束页面特征图路径
END_PAGE_IMAGE = './logo.png'

# 下一个按钮在播放器窗口内的相对位置 (X, Y)
NEXT_BUTTON_POS = (432, 951)

# 图像匹配阈值 (0.7-0.9)
CONFIDENCE_THRESHOLD = 0.8

# 检测间隔(秒)
CHECK_INTERVAL = 5

# 结束页面关键词
TEXT_TRIGGERS = ["播放结束", "THE END", "播放完毕", "重播", "视频播放结束", "END"]

# Tesseract OCR路径
TESSERACT_PATH = r'D:\Program Files\Tesseract-OCR\tesseract.exe'
# ===== 配置结束 =====

# 初始化dxcam相机
camera = None

def init_dxcam():
    """初始化高性能截图库"""
    global camera
    try:
        # 创建dxcam实例，使用默认设备
        camera = dxcam.create()
        if camera is None:
            print("无法创建dxcam实例。")
            return False
        return True
    except Exception as e:
        print(f"初始化dxcam失败: {e}")
        return False

def get_player_window_rect():
    """
    获取播放器窗口的位置和大小（即使它在后台）
    返回: (left, top, width, height) 或 None
    """
    def callback(hwnd, extra):
        if win32gui.IsWindowVisible(hwnd):
            window_title = win32gui.GetWindowText(hwnd)
            if PLAYER_WINDOW_TITLE in window_title:
                # 找到播放器窗口
                rect = win32gui.GetWindowRect(hwnd)
                extra['rect'] = rect
                extra['hwnd'] = hwnd

    extra_info = {'rect': None, 'hwnd': None}
    win32gui.EnumWindows(callback, extra_info)

    if extra_info['rect'] is None:
        print(f"未找到标题包含 '{PLAYER_WINDOW_TITLE}' 的窗口")
        return None, None

    left, top, right, bottom = extra_info['rect']
    width = right - left
    height = bottom - top
    print(f"播放器窗口位置: 左={left}, 上={top}, 宽={width}, 高={height}")

    # 检查窗口是否最小化
    if win32gui.IsIconic(extra_info['hwnd']):
        print("播放器窗口已最小化，无法捕获。")
        return None, None

    return extra_info['hwnd'], (left, top, width, height)

def capture_window_region(region):
    """
    使用dxcam捕获指定区域
    region: (left, top, width, height)
    返回: 截图（RGB格式的numpy数组）或 None
    """
    if camera is None:
        print("dxcam未初始化")
        return None

    left, top, width, height = region
    # dxcam的grab方法要求区域为(left, top, right, bottom)
    capture_region = (left, top, left + width, top + height)
    try:
        img = camera.grab(region=capture_region)
        if img is None:
            print("截图失败（dxcam.grab返回None）")
            return None
        # dxcam返回的是BGRA格式，转换为RGB
        return cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
    except Exception as e:
        print(f"截图异常: {e}")
        return None

def image_detected(screen_np, template_path):
    """
    使用模板匹配检测结束图像
    screen_np: 屏幕截图（RGB格式）
    template_path: 模板图片路径
    返回: 匹配度是否超过阈值
    """
    try:
        template = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE)
        if template is None:
            print(f"无法读取模板图片: {template_path}")
            return False
            
        gray_screen = cv2.cvtColor(screen_np, cv2.COLOR_RGB2GRAY)
        result = cv2.matchTemplate(gray_screen, template, cv2.TM_CCOEFF_NORMED)
        _, max_val, _, _ = cv2.minMaxLoc(result)
        
        print(f"图像匹配相似度: {max_val:.4f}")  # 调试信息
        
        return max_val >= CONFIDENCE_THRESHOLD
    except Exception as e:
        print(f"图像匹配出错: {e}")
        return False

def image_to_text(image_np):
    """
    从图像中提取文字
    image_np: RGB格式的截图
    返回: 识别的文字
    """
    try:
        gray = cv2.cvtColor(image_np, cv2.COLOR_RGB2GRAY)
        # 二值化处理，提高识别率
        _, threshold = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
        # 使用Tesseract进行文字识别（简体中文+英文）
        text = pytesseract.image_to_string(threshold, lang='chi_sim+eng')
        return text
    except Exception as e:
        print(f"文字识别出错: {e}")
        return ""

def trigger_action(window_rect):
    """
    执行点击操作
    window_rect: (left, top, width, height)
    """
    # 计算屏幕上的绝对坐标
    abs_x = window_rect[0] + NEXT_BUTTON_POS[0]
    abs_y = window_rect[1] + NEXT_BUTTON_POS[1]
    
    # 激活窗口（将其前置）
    hwnd, _ = get_player_window_rect()
    if hwnd:
        # 如果窗口最小化，则恢复
        if win32gui.IsIconic(hwnd):
            win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
        win32gui.SetForegroundWindow(hwnd)
        time.sleep(0.5)  # 等待窗口激活
    
    # 移动鼠标并点击
    pyautogui.moveTo(abs_x, abs_y, duration=0.5)
    pyautogui.click()
    print(f"已点击位置: ({abs_x}, {abs_y})")

def capture_end_page_image():
    """截取结束页面作为模板"""
    print("请确保视频处于结束页面状态...")
    print("将在5秒后截取屏幕...")
    time.sleep(5)
    
    # 获取播放器窗口位置
    hwnd, window_rect = get_player_window_rect()
    if hwnd is None or window_rect is None:
        print("无法获取播放器窗口")
        return
    
    # 截取窗口区域
    screenshot = capture_window_region(window_rect)
    if screenshot is None:
        print("截图失败")
        return
    
    # 保存为PNG
    img = Image.fromarray(screenshot)
    img.save(END_PAGE_IMAGE)
    print(f"已保存结束页面截图: {END_PAGE_IMAGE}")

def main():
    # 设置Tesseract路径
    pytesseract.pytesseract.tesseract_cmd = TESSERACT_PATH

    # 初始化dxcam
    if not init_dxcam():
        print("初始化失败，退出程序。")
        return

    print("="*50)
    print("视频自动播放助手 - Python 3.13.3版")
    print(f"正在监控窗口标题包含 '{PLAYER_WINDOW_TITLE}' 的播放器...")
    print("按 Ctrl+C 退出")
    print("="*50)

    # 首次运行帮助
    if input("是否需要截取结束页面图像? (y/n): ").lower() == 'y':
        capture_end_page_image()
        print("请重新运行脚本开始监控")
        return

    try:
        while True:
            # 获取播放器窗口位置
            hwnd, window_rect = get_player_window_rect()
            if hwnd is None or window_rect is None:
                print(f"{CHECK_INTERVAL}秒后重试...")
                time.sleep(CHECK_INTERVAL)
                continue

            # 捕获播放器窗口区域
            screenshot = capture_window_region(window_rect)
            if screenshot is None:
                print(f"截图失败，{CHECK_INTERVAL}秒后重试...")
                time.sleep(CHECK_INTERVAL)
                continue

            # 检测结束页面
            end_detected = False

            # 方式1: 图像匹配
            if END_PAGE_IMAGE:
                end_detected = image_detected(screenshot, END_PAGE_IMAGE)
                if end_detected:
                    print("图像匹配: 检测到结束页面")

            # 方式2: OCR文字识别
            if not end_detected and TEXT_TRIGGERS:
                text = image_to_text(screenshot)
                print(f"OCR识别结果: {text.strip()}")
                if any(trigger in text for trigger in TEXT_TRIGGERS):
                    print("文字匹配: 检测到结束页面")
                    end_detected = True

            # 如果检测到结束页面，则执行点击
            if end_detected:
                trigger_action(window_rect)
                # 点击后等待一段时间，避免连续检测
                time.sleep(10)  # 等待新视频开始

            time.sleep(CHECK_INTERVAL)

    except KeyboardInterrupt:
        print("\n退出程序。")

if __name__ == "__main__":
    main()